def closures_in_loop_block(nclosures=5)
  closures = []; #Defining an Array that will hold the closures
  nclosures.times do |i|
    closures << lambda{"Actual: i = #{i}"};
  end
  closures;
end

def closures_in_loop(nclosures=5)
  closures = []; #Defining an Array that will hold the closures
  i = 0;
  while i < nclosures
    closures << lambda{"Actual: i = #{i}"};
    i += 1;
  end
  closures;
end

def closures_var_after
  closures = []; #Defining an Array that will hold the closures
  i = 0;
  closures << lambda{"Actual: i = #{i}"};
  i = 1;
  closures << lambda{i = 2; "Actual: i = #{i}"};
  i = 3;
  closures << lambda{"Actual: i = #{i}"};
  closures;
end

def debug_closures(closures, title="")
  puts title;
  closures.each_with_index{|cl, n| puts "Closure #{n}: "+cl.call}
  puts "\n\n";
end

# The closures will handle each variable i because it wasn't defined in the method
debug_closures(closures_in_loop_block, "Closures in a loop iterated by passing it\n a code block")

# The closures will handle the last variable value because it was defined in the method
debug_closures(closures_in_loop, "Closures in a while statement")

# In the loop to call the closures: The 1st is called and retain the last i value (3).
# The 2nd is called and modify the outside i value to 2, and show it.
# With the i value modified outside by the 2nd closure, the 3rd one shows the 
# modified value that is 2.
debug_closures(closures_var_after, "Closures with variable defining")
